package com.lemon.components.wechart.impl;

import java.util.Iterator;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lemon.components.wechart.WechartBase;
import com.lemon.components.wechart.WechartUserService;
import com.lemon.components.wechart.order.user.RefreshUserTokenOrder;
import com.lemon.components.wechart.order.user.UserAccessTokenOrder;
import com.lemon.components.wechart.order.user.UserCodeOrder;
import com.lemon.components.wechart.order.user.UserInfoOrder;
import com.lemon.components.wechart.result.user.RefreshUserTokenResult;
import com.lemon.components.wechart.result.user.UserAccessTokenResult;
import com.lemon.components.wechart.result.user.UserInfoResult;
import com.lemon.components.wechart.result.user.WechartToken;

@Service
public class WechartUserServiceImpl extends WechartBase implements WechartUserService {

	/**
	 * 获取访问token地址
	 */
	private static final String GETTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%1$s&secret=%2$s";
	/**
	 * 获得user code地址
	 */
	private static final String GETCODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%1$s&redirect_uri=%2$s&response_type=code&scope=%3$s%4$s#wechat_redirect";
	/**
	 * 获得user访问token地址
	 */
	private static final String GETACCESSTOKEN_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=%4$s";
	/**
	 * 获得刷新token地址
	 */
	private static final String REFRESH_USER_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%1$s&grant_type=%2$s&refresh_token=%3$s";
	private static final String GET_USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%1$s&openid=%2$s&lang=zh_CN";
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Override
	public WechartToken getToken(String appid, String appsecret) {
		WechartToken wechartToken = new WechartToken();
		if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)){
			wechartToken.setErrcode(-2);
			wechartToken.setErrmsg("参数为空，请传入appid和appsecret参数");
			return wechartToken;
		}
		String str = postCommand(String.format(GETTOKEN_URL, appid, appsecret), null);
		JSONObject jsonObject = JSONObject.parseObject(str);
		int errcode = jsonObject.getIntValue("errcode");
		if (errcode > 0) {
			wechartToken.setErrcode(errcode);
			wechartToken.setErrmsg(jsonObject.getString("errmsg"));
			return wechartToken;
		} else {
			wechartToken.setAccessToken(jsonObject.getString("access_token"));
			wechartToken.setExpiresIn(jsonObject.getLongValue("expires_in"));
		}
		return wechartToken;
	}
	
	@Override
	public String getUserCodeUrl(UserCodeOrder userCodeOrder){
		userCodeOrder.check();
		String str = String.format(GETCODE_URL, 
				userCodeOrder.getAppid(), 
				userCodeOrder.getRedirectUri(),
				userCodeOrder.getScope().getCode(),
				userCodeOrder.getState()
			);
		logger.info("[微信]获取访问code地址为：{}",str);
		return str;
	}
	
	@Override
	public UserInfoResult getUserInfo(UserInfoOrder userInfoOrder){
		userInfoOrder.check();
		UserInfoResult result = new UserInfoResult();
		String str = getCommand(String.format(GET_USER_INFO_URL, userInfoOrder.getAccessToken(),userInfoOrder.getOpenid()));
		JSONObject jsonObject = JSONObject.parseObject(str);
		int errcode = jsonObject.getIntValue("errcode");
		if (errcode > 0) {
			result.setErrcode(errcode);
			result.setErrmsg(jsonObject.getString("errmsg"));
			return result;
		} else {
			result.setOpenid(jsonObject.getString("openid"));
			result.setSubscribe(jsonObject.getIntValue("subscribe"));
			result.setNickname(jsonObject.getString("nickname"));
			result.setSex(jsonObject.getIntValue("sex"));
			result.setCity(jsonObject.getString("city"));
			result.setCountry(jsonObject.getString("country"));
			result.setProvince(jsonObject.getString("province"));
			result.setLanguage(jsonObject.getString("language"));
			result.setHeadimgurl(jsonObject.getString("headimgurl"));
			result.setSubscribeTime(jsonObject.getLongValue("subscribe_time"));
			result.setUnionid(jsonObject.getString("unionid"));
			result.setRemark(jsonObject.getString("remark"));
			result.setGroupid(jsonObject.getIntValue("groupid"));
			JSONArray tagidLists = jsonObject.getJSONArray("tagid_list");
			if(tagidLists.size()>0){
				int[] tagidListValue = new int[tagidLists.size()];
				int index = 0;
				for(Iterator<Object> iter = tagidLists.iterator();iter.hasNext();index ++){
					int tagid = (Integer)iter.next();
					tagidListValue[index] = tagid;
				}
				result.setTagidList(tagidListValue);
			}
		}
		return result;
	}
	/**
	 * 更新用户token
	 */
	@Override
	public RefreshUserTokenResult refreshUserToken(RefreshUserTokenOrder refreshUserTokenOrder){
		refreshUserTokenOrder.check();
		RefreshUserTokenResult result = new RefreshUserTokenResult();
		String str = getCommand(String.format(REFRESH_USER_TOKEN_URL, refreshUserTokenOrder.getAppid(),refreshUserTokenOrder.getGrantType(),refreshUserTokenOrder.getRefreshToken()));
		JSONObject jsonObject = JSONObject.parseObject(str);
		int errcode = jsonObject.getIntValue("errcode");
		if (errcode > 0) {
			result.setErrcode(errcode);
			result.setErrmsg(jsonObject.getString("errmsg"));
			return result;
		} else {
			result.setOpenid(jsonObject.getString("openid"));
			result.setAccessToken(jsonObject.getString("access_token"));
			result.setExpiresIn(jsonObject.getLongValue("expires_in"));
			result.setRefreshToken(jsonObject.getString("refresh_token"));
			result.setScope(jsonObject.getString("scope"));
		}
		return result;
	}
	
	/**
	 * 获取OpenID
	 * @param userAccessTokenOrder
	 * @return
	 */
	@Override
	public UserAccessTokenResult getUserAccessToken(UserAccessTokenOrder userAccessTokenOrder){
		userAccessTokenOrder.check();
		UserAccessTokenResult result = new UserAccessTokenResult();
		String str = getCommand(String.format(GETACCESSTOKEN_URL, userAccessTokenOrder.getAppid(), userAccessTokenOrder.getSecret(),userAccessTokenOrder.getCode(),userAccessTokenOrder.getGrantType()));
		JSONObject jsonObject = JSONObject.parseObject(str);
		int errcode = jsonObject.getIntValue("errcode");
		if (errcode > 0) {
			result.setErrcode(errcode);
			result.setErrmsg(jsonObject.getString("errmsg"));
			return result;
		} else {
			result.setOpenid(jsonObject.getString("openid"));
			result.setAccessToken(jsonObject.getString("access_token"));
			result.setExpiresIn(jsonObject.getLongValue("expires_in"));
			result.setRefreshToken(jsonObject.getString("refresh_token"));
			result.setScope(jsonObject.getString("scope"));
		}
		return result;
	}
}
